package com.wtone.platform.gat.images.gat.aspect;

import com.alibaba.fastjson.JSON;
import com.wtone.platform.gat.images.gat.core.Constants;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

/**
 * @Author: aiLin
 * @Date: 2020/4/24 11:35
 * @desc: 日志切面拦截
 */
@Slf4j
@Aspect
@Component
public class LogAspect {

    /*切点为controller包下面的所有类的所有方法*/
    @Pointcut("execution(public * com.wtone.platform.gat.images.gat.service.impl.*.*(..))")
    public void log() {

    }

    /*进入方法之前执行*/
    @Before("log()")
    public void doBefore(JoinPoint joinPoint) {
        ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
        HttpServletRequest request = attributes.getRequest();
        String method = request.getMethod();
        String params = "";
        log.info("---------------请求日志begin---------------");
        //url
        log.info("url:{}", request.getRequestURL());
        //method 类型（GET ,POST .....）
        log.info("method:{}", request.getMethod());
        //ip
        log.info("ip:{}", getIpAddr(request));
        //请求验证参数
        log.info("User-Identify:{}", request.getHeader(Constants.REQTOKEN));
        //类方法
        //log.info("class_method:{}",joinPoint.getSignature().getDeclaringTypeName() +"."+ joinPoint.getSignature().getName());
        //参数
        //log.info("args:{}",params);
        // 请求的参数
        Map<String, String> rtnMap = converMap(request.getParameterMap());
        // 将参数所在的数组转换成json
        params = JSON.toJSONString(rtnMap);
        if ("POST".equals(method)) {
            Object[] paramsArray = joinPoint.getArgs();
            String param = argsArrayToString(paramsArray);
            params += argsArrayToString(paramsArray)+",";
        }
        log.info("args : {}", Arrays.toString(joinPoint.getArgs()));
    }

    /**
     * 转换request 请求参数
     * @param paramMap request获取的参数数组
     */
    public Map<String, String> converMap(Map<String, String[]> paramMap) {
        Map<String, String> rtnMap = new HashMap<String, String>();
        for (String key : paramMap.keySet()) {
            rtnMap.put(key, paramMap.get(key)[0]);
        }
        return rtnMap;
    }

    /**
     * 请求参数拼装
     * @param paramsArray
     * JSON.toJSON(paramsArray[i])
     * UserInfo(ip=10.6.254.15, port=8000, userNmae=admin, passWord=a1234567)
     * {"passWord":"a1234567","port":8000,"userNmae":"admin","ip":"10.6.254.15"}
     * @return
     */
    private String argsArrayToString(Object[] paramsArray) {
        String params = "";
        if (paramsArray != null && paramsArray.length > 0) {
            for (int i = 0; i < paramsArray.length; i++) {
                if(paramsArray[i]!=null){
                    Object jsonObj = JSON.toJSON(paramsArray[i]);
                    params += jsonObj.toString()+ " ";
                }
            }
        }
        return params.trim();
    }

    /*方法执行之后执行*/
        /*@After("log()")
        public void doAfter(){
            log.info("方法执行之后执行doAfter："+DateUtils.getTime());
        }*/

    //controller中结果返回之后调用
    @AfterReturning(returning = "object", pointcut = "log()")
    public void doAfterReturning(Object object) {
        if(object!=null){
            log.info("response={}", object.toString());//拦截到void类型的方法也会报错
        }
        log.info("---------------请求日志end-----------------");
    }

    /**
     * 获取登录用户远程主机ip地址
     *
     * @param request
     * @return
     */
    private String getIpAddr(HttpServletRequest request) {
        String ip = request.getHeader("x-forwarded-for");
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getHeader("WL-Proxy-Client-IP");
        }
        if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
            ip = request.getRemoteAddr();
        }
        return ip;
    }




}
